#include "sensetime_protocol.h"
#include "face.h"
#include "face_common.h"
#include "face_encrypt.h"

static Master_Msg_Cb_fun_t masterMsgcb = NULL; //主控发送任务回调
#define SENSETIME_PROTOCOL_LOG(format, ...) OSAL_LOG(C_CYAN format C_NONE, ##__VA_ARGS__)


extern void Face_Event_Deal(Face_DealParam_stu_t *param);
extern void Face_TxCmdRingBuffWrite(SensetimeTxCmdMsg_stu_t *pData);

/*******************************************************************************/
/******************       发送消息给人脸模组处理          ************************/
/*******************************************************************************/

/**
  * @brief  发消息给队列
  *
  * @param  cmd：命令
  * @param  pData：数据域指针
  * @param  dataLen：数据长度
  * @param  cb：reply回调函数
  */
static void Sensetime_SendCmdToRingBuff(uint8_t cmd, uint8_t *pData, uint16_t dataLen, FaceMessageCallback_fun_t cb, uint32_t timeout)
{
	SensetimeTxCmdMsg_stu_t msgData;
	msgData.msgID = cmd;
	msgData.cb = cb;
	msgData.timeout = timeout;
	msgData.data_len = dataLen;
	memcpy(msgData.dataBuf, pData, dataLen);
	Face_TxCmdRingBuffWrite(&msgData);

}

/*******************************************************************************/
/******************       人脸模组note信息处理          *************************/
/*******************************************************************************/

/**
  * @brief  处理人脸模组上电准备好note信息
  * @note   开机时模块向主控发送NID_READY
  *
  */
void Sensetime_Nid_Ready(void)
{
	SENSETIME_PROTOCOL_LOG("Module power on ready");
	Face_DealParam_stu_t DealParam;
	DealParam.event = FACE_EVENT_POWER_ON_READY; //模组上电完成
	Face_Event_Deal(&DealParam);					//人脸模组事件处理
}

/**
  * @brief  处理人脸模组返回的人脸状态信息
  * @note   验证和录入过程中会收到对应信息
  *	
  */
void Sensetime_Nid_Face_Status(uint8_t *pNoteDataBuf)
{
	s_note_data_face *pFaceStatus = (s_note_data_face *)pNoteDataBuf;
	Face_DealParam_stu_t DealParam;

	DealParam.result = pFaceStatus->status;
	DealParam.event = FACE_EVENT_NID_FACE_STATUS; //录入和验证人脸状态信息返回:人脸状态信息返回
	DealParam.data = pFaceStatus;
	Face_Event_Deal(&DealParam);			  //人脸模组事件处理

}

/**
  * @brief  处理人脸模组OTA状态信息
  * @note   OTA升级过程中会收到对应信息
  *
  */
void Sensetime_Nid_Ota_Done(uint8_t *pNoteDataBuf)
{
	Face_DealParam_stu_t DealParam;

	switch (pNoteDataBuf[0])
	{
		case 0: //OTA sucess
			DealParam.result = RESULT_SUCCESS_REPORT;
			break;

		case 1: //OTA fail
		default:
			DealParam.result = RESULT_FAIL_REPORT;
			break;
	}

	DealParam.event = FACE_EVENT_OTA_FINISH; //OTA结束
	Face_Event_Deal(&DealParam);		//人脸模组事件处理

}

extern int32_t Face_Search_Index(uint8_t *userId);
extern int32_t Face_Search_Compare(uint8_t *userId);
extern void Face_Read_All_UserId(void);


/*******************************************************************************/
/***************       操作指令的reply回调函数处理   START    ********************/
/*******************************************************************************/



/**
  * @brief  对比版本号
  * 
  * @param  
  * @note
  *
  * @return 
  */
static ErrorStatus Funmenu_Compare_Vesion(uint8_t *pData, uint8_t dataLen, uint8_t *pVersion, uint8_t *versionLen)
{
	ErrorStatus ret = ERROR;
	uint8_t version_type[] = {'V', 0, '.', 0, '.', 0, 0, 0}; //0不参与匹配
	uint8_t i, j;
	uint8_t len_buf = OSAL_LENGTH(version_type);
	for (i = 0; i < dataLen - len_buf; i++)
	{
		for (j = 0; j < len_buf; j++)
		{
			if ((pData[i + j] != version_type[j]) && (version_type[j] != 0))
				break;
		}

		if (j == len_buf)
		{
			for (j = 0; j < len_buf; j++)
			{
				pVersion[j] = pData[i + j];
			}
			*versionLen = len_buf;
			ret = SUCCESS;
			break;
		}
	}
	return ret;
}


static ErrorStatus _get_version(uint8_t *pData, uint8_t dataLen, uint8_t *pVersion, uint8_t *pModel)
{
	ErrorStatus ret = ERROR;
	uint8_t i = 0, j = 0;
	uint8_t head = 0;
	uint8_t len_buf = 0;

	/* 字符截取 */
	for (i = 0; i < dataLen; i++)
	{
		if (!(pData[i] >= 0x20 && pData[i] <= 0x7E)) //可显字符
		{
			break;
		}
	}
	len_buf = i;
	if (len_buf >= dataLen)
	{
		return ERROR;
	}

	/* 解析型号 */
	for (i = 0; i < len_buf; i++)
	{
		if (pData[i] == '_')
		{
			break;
		}
	}
	if (i <= FACE_MODEL_LEN)
	{
		memcpy(pModel, pData, i);
	}

	/* 解析版本号 */
	for (i = 0; i < len_buf; i++)
	{
		if (pData[i] >= 'A' && pData[i] <= 'Z') //最后一个大写字母后面为版本号
		{
			memset(pVersion, 0, j);
			head = 1;
			j = 0;
		}	
		if (head)
		{
			pVersion[j++] = pData[i];
		}
	}

	if (j && j < FACE_VERSION_LEN)
	{
		/* 校验版本号格式 */
		for (i = 1; i < j; i++)
		{
			if (!((pVersion[i] >= '0' && pVersion[i] <= '9') || pVersion[i] == '.'))
			{
				memset(pVersion, 0, FACE_VERSION_LEN);
				return ERROR;
			}
		}
		ret = SUCCESS;
	}
	return ret;
}



extern ErrorStatus Face_WriteFaceVersion(uint8_t *pData, uint8_t len);
extern ErrorStatus Face_Write_Model(uint8_t *pData);
/**
  * @brief  0x30获取软件版本消息给人脸模组回调
  * 
  * @note
  */
static void Sensetime_Get_Version_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_reply_version_data *pdatabuf = (s_msg_reply_version_data *)data;
	Face_DealParam_stu_t DealParam;

	uint8_t version[FACE_VERSION_LEN] = {0};
	uint8_t model[FACE_MODEL_LEN] = {0};
	uint8_t versionLen = 0;

	DealParam.event = FACE_EVENT_SET_FINISH;

	switch (result)
	{
	case MR_SUCCESS: //成功
		if (SUCCESS == _get_version(pdatabuf->version_info, VERSION_INFO_BUFFER_SIZE, version, model))
		{
			DealParam.result = RESULT_SUCCESS_REPORT;
			SENSETIME_PROTOCOL_LOG("get ver success: model: %s, ver: %s",model,version);
			Face_WriteFaceVersion(version, versionLen);
			Face_Write_Model(model);
		}
		else
		{
			SENSETIME_PROTOCOL_LOG("get ver error: model: %s, ver: %s",model,version);
		}
		break;

	default:
		DealParam.result = RESULT_FAIL_REPORT;
		break;
	}

	Face_Event_Deal(&DealParam);		 //人脸模组事件处理
}

/**
  * @brief  0x53设置临时加密key reply回调
  * 
  * @param  
  * @note
  *
  * @return 
  */
static void Sensetime_DebugEncrytionKeyNum_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	Face_DealParam_stu_t DealParam;

	DealParam.result = FACE_TASK_MSGID_MAX; //无效值
	DealParam.event = FACE_EVENT_DEBUG_ENC_READY;
	switch (result)
	{
	case MR_SUCCESS: //成功
		DealParam.result = RESULT_SUCCESS_REPORT; 
		break;

	default:
		DealParam.result = RESULT_FAIL_REPORT; 
		break;
	}
	Face_Event_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  0x50初始化随机数（设置加密模式）reply回调
  * 
  * @note
  */
static void Sensetime_InitEncryption_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_reply_init_encryption_data *pdata = (s_msg_reply_init_encryption_data *)data;
	Face_DealParam_stu_t DealParam;

	DealParam.result = FACE_TASK_MSGID_MAX; //无效值
	DealParam.event = FACE_EVENT_INIT_ENCRYPTION_READY;

	switch (result)
	{
	case MR_SUCCESS:								//成功
		DealParam.data = pdata->device_id;
		DealParam.result = RESULT_SUCCESS_REPORT; 
		break;

	default:
		DealParam.result = RESULT_FAIL_REPORT; 
		break;
	}
	Face_Event_Deal(&DealParam); //人脸模组事件处理
}


/**
  * @brief  人脸录入reply结果回调
  * @param  result：结果
  * @param  data：返回的数据
  * @param  len: 数据长度
  * @note
  */
static void Sensetime_Enroll_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	s_msg_reply_enroll_data *pdatabuf = (s_msg_reply_enroll_data *)data;
	Face_DealParam_stu_t DealParam;

	
	DealParam.data = pdatabuf;
	switch (result)
	{
	case MR_SUCCESS:
		//单帧录入
		DealParam.result = RESULT_SUCCESS_REPORT;	  //录入成功
		DealParam.event = FACE_EVENT_ENROLL_SUCCESS; 
		break;

	case MR_FAILED4_FACEENROLLED:					  //人脸已录入
		DealParam.result = RESULT_FACE_ENROLLED;
		DealParam.event = FACE_EVENT_ENROLL_FAIL; 
		break;

	case MR_FAILED4_MAXUSER: //录入超过最大用户数量
		SENSETIME_PROTOCOL_LOG("face enroll max user");
	default:
		DealParam.result = RESULT_FAIL_REPORT;		  //失败
		DealParam.event = FACE_EVENT_ENROLL_FAIL; 
		break;
	}
	SENSETIME_PROTOCOL_LOG("send enrolling result = %d, num_L=0X%2X, num_H=0X%2X, dir=0X%2X", result, pdatabuf->user_id_leb, pdatabuf->user_id_heb, pdatabuf->face_direction);
	Face_Event_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  人脸验证reply回调
  * 
  * @note
  */
void Sensetime_Verity_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	s_msg_reply_verify_data *pdatabuf = (s_msg_reply_verify_data *)data;
	Face_DealParam_stu_t DealParam;

	//DealParam.event = FACE_EVENT_VERIFY_SUCCESS;
	DealParam.data = pdatabuf;

	switch (result)
	{
	case MR_SUCCESS: //成功
		DealParam.result = RESULT_SUCCESS_REPORT;
		DealParam.event = FACE_EVENT_VERIFY_SUCCESS; 


		/* 比对本地id库 */
		uint16_t face_id = (pdatabuf->user_id_heb << 8 ) | pdatabuf->user_id_leb;
		SENSETIME_PROTOCOL_LOG("verify search index");
		if(Face_Search_Index((uint8_t *)&face_id) != pdatabuf->user_name[0])
		{
			/* 删除无用id */
			SENSETIME_PROTOCOL_LOG("can't find id, delete and verify again\r\n");
			Sensetime_Send_Start_DelUser_CMD(face_id);
			/* 重新验证 */
			Sensetime_Send_StartVerity_CMD(1);
			return;
		}
		break;

	case MR_FAILED4_WITHOUTSMILE:
		SENSETIME_PROTOCOL_LOG("no smile\r\n");
		DealParam.result = RESULT_VERIFY_FAIL_REPORT;
		DealParam.event = FACE_EVENT_VERIFY_FAIL; //人脸验证结束
		break;
	
	case MR_FAILED4_UNKNOWNUSER:
		SENSETIME_PROTOCOL_LOG("unknown face\r\n");
		DealParam.result = RESULT_VERIFY_FAIL_REPORT;
		DealParam.event = FACE_EVENT_VERIFY_FAIL; //人脸验证结束
		break;

	default:
		DealParam.result = RESULT_FAIL_REPORT;
		DealParam.event = FACE_EVENT_VERIFY_FAIL; //人脸验证结束
		break;
	}

	SENSETIME_PROTOCOL_LOG("send startverity result = %d,usernum = %02d,id = 0x%02x%02x", 
						result, pdatabuf->user_name[0], pdatabuf->user_id_heb, pdatabuf->user_id_leb);

	Face_Event_Deal(&DealParam); //人脸模组事件处理
}


/**
  * @brief  删除单个用户reply回调
  * 
  * @note
  */
static void Sensetime_DelUser_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	Face_DealParam_stu_t DealParam;

	DealParam.event = FACE_EVENT_DELETE_FINISH; //删除完成
	switch (result)
	{
	case MR_SUCCESS:
		DealParam.result = RESULT_SUCCESS_REPORT;	//删除成功
		break;

	default:
		DealParam.result = RESULT_FAIL_REPORT;		//失败
		break;
	}
	SENSETIME_PROTOCOL_LOG("send deleting user result = %#2x", result);
	Face_Event_Deal(&DealParam); //人脸模组事件处理
}


/**
  * @brief  删除全部用户reply回调
  * 
  * @note
  */
static void Sensetime_DelAll_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	Face_DealParam_stu_t DealParam;

	DealParam.event = FACE_EVENT_DELETE_FINISH; //删除完成
	switch (result)
	{
	case MR_SUCCESS:
		
		DealParam.result = RESULT_SUCCESS_REPORT;	//删除成功
		break;

	default:
		DealParam.result = RESULT_FAIL_REPORT;		//失败
		break;
	}
	SENSETIME_PROTOCOL_LOG("send deleting user result = %#2x", result);
	Face_Event_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  终止当前操作回调
  * 
  * @note
  */
void Sensetime_Reset_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	Face_DealParam_stu_t DealParam;

	switch (result)
	{
	case MR_SUCCESS:							  //成功
		DealParam.event = FACE_EVENT_ABORT_FINISH; //成功进入IDLE模式
		DealParam.result = RESULT_SUCCESS_REPORT;
		break;

	default:
		DealParam.event = FACE_ENENT_TIMEOUT; //当做超时
		DealParam.result = RESULT_FAIL_REPORT;
		break;
	}

	Face_Event_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  指令掉电操作回调
  * 
  * @note
  */
void Sensetime_PowerDowm_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	Face_DealParam_stu_t DealParam;

	switch (result)
	{
	case MR_SUCCESS:							  //成功
		DealParam.event = FACE_EVENT_SLEEP_FINISH; 
		DealParam.result = RESULT_SUCCESS_REPORT;
		break;

	default:
		DealParam.event = FACE_ENENT_TIMEOUT; //当做超时
		DealParam.result = RESULT_FAIL_REPORT;
		break;
	}

	SENSETIME_PROTOCOL_LOG("send powerDown result = %#2x", result);
	Face_Event_Deal(&DealParam); //人脸模组事件处理
}


/**
  * @brief  0x52人脸设置量产加密秘钥序列回调
  * 
  * @note
  */
static void Sensetime_ReleaseEncrytionKeyNum_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	Face_DealParam_stu_t DealParam;

	DealParam.event = FACE_EVENT_SET_FINISH;

	switch (result)
	{
		case MR_SUCCESS: //成功
			DealParam.result = RESULT_SUCCESS_REPORT;
			break;

		case MR_REJECTED:						   //模块拒接该命令
			DealParam.result = RESULT_ENCRYPTED; //已加密
			break;

		default:
			DealParam.result = RESULT_FAIL_REPORT;
			break;
	}
	
	Face_Event_Deal(&DealParam); //人脸模组事件处理
}


/**
  * @brief  人脸设置debug模式回调
  * 
  * @note
  */
static void Sensetime_SetDebugMode_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	Face_DealParam_stu_t DealParam;

	DealParam.event = FACE_EVENT_SET_FINISH; //设置结束
	switch (result)
	{
	case MR_SUCCESS: //成功
		DealParam.result = RESULT_SUCCESS_REPORT;
		break;

	default:
		DealParam.result = RESULT_FAIL_REPORT;
		break;
	}
	
	Face_Event_Deal(&DealParam);		 //人脸模组事件处理
}

/**
  * @brief  人脸启动升级回调
  * @note
  *
  */
static void Sensetime_StartOta_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	Face_DealParam_stu_t DealParam;
	DealParam.data = &data;

	switch (result)
	{
	case MR_SUCCESS: //成功
		DealParam.result = RESULT_SUCCESS_REPORT;
		DealParam.event = FACE_EVENT_OTA_READY; //OTA 前期准备
		break;

	default:
		DealParam.result = RESULT_FAIL_REPORT;
		DealParam.event = FACE_EVENT_OTA_FINISH; //OTA结束
		break;
	}
	
	Face_Event_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  人脸获取模块OTA状态回调
  * 
  * @note
  */
static void Sensetime_GetOtaStatus_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_reply_getOtaStatus_data *pdatabuf = (s_msg_reply_getOtaStatus_data *)data;

	Face_DealParam_stu_t DealParam;
	DealParam.data = pdatabuf;

	switch (result)
	{
		case MR_SUCCESS: //成功
			DealParam.result = RESULT_SUCCESS_REPORT;
			DealParam.event = FACE_EVENT_OTA_READY; //OTA 前期准备
			break;

		default:
			DealParam.result = RESULT_FAIL_REPORT;
			DealParam.event = FACE_EVENT_OTA_FINISH; //OTA结束
			break;
	}
	
	Face_Event_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  发送结束升级的消息给人脸模组回调
  * 
  * @note
  */
static void Sensetime_StopOta_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	Face_DealParam_stu_t DealParam ;

	DealParam.result = RESULT_FAIL_REPORT;
	DealParam.event = FACE_EVENT_OTA_FINISH; //OTA结束

	Face_Event_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  获取全部已注册的人脸id
  * 
  * @note
  */
static void Sensetime_GetAllUserid_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_reply_all_userid_data *pdatabuf = (s_msg_reply_all_userid_data *)data;
	uint16_t face_id;
	Face_DealParam_stu_t DealParam;
	DealParam.data = pdatabuf;

	switch (result)
	{
		case MR_SUCCESS: //成功
			DealParam.result = RESULT_SUCCESS_REPORT;
			DealParam.event = FACE_EVENT_GET_ALL_USERID; //获取完成
			SENSETIME_PROTOCOL_LOG("all user_counts: %d\r\n",pdatabuf->user_counts);
			Face_Read_All_UserId();
			printf("user_num: user_id \r\n");
			for(uint8_t i = 0;i<pdatabuf->user_counts;i++)
			{
				//printf("0X%02X%02X ",pdatabuf->users_id[i*2],pdatabuf->users_id[i*2+1]);
				face_id = (pdatabuf->users_id[i*2] << 8 ) | pdatabuf->users_id[i*2+1];

				/* 比对本地id库 */
				if(Face_Search_Compare((uint8_t *)&face_id) != 1)
				{
					/* 删除无用id */
					printf("can't find id: 0X%X, delete\r\n",face_id);
					Sensetime_Send_Start_DelUser_CMD(face_id);
					return;
				}

			}
			printf("\r\n");

			break;

		default:
			DealParam.result = RESULT_FAIL_REPORT;
			DealParam.event = FACE_ENENT_TIMEOUT; //
			break;
	}
	
	Face_Event_Deal(&DealParam); //人脸模组事件处理
}

/*******************************************************************************/
/********************       reply回调函数处理   END      ************************/
/*******************************************************************************/

/*******************************************************************************/
/********************       操作指令发送函数   START     ************************/
/*******************************************************************************/

/**
  * @brief  发送0x1D人脸录入
  * 
  * @param  num:人脸编号
  * 
  * @note
  */
void Sensetime_Send_StartEnroll_CMD(uint8_t num)
{
	uint8_t len = sizeof(s_msg_enroll_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_enroll_data *pdatabuf = (s_msg_enroll_data *)databuf;

	pdatabuf->face_direction = 0;
	pdatabuf->user_name[0] = num;
	pdatabuf->admin = 0;
	FaceMessageCallback_fun_t cb = Sensetime_Enroll_Callback;
	pdatabuf->timeout = (FACE_ENROLLING_TIMEOUT - FACE_MODULE_DEAL_TIMEOUT_SMALL) / FACE_ONE_SEC_OF_MSEC;
	Sensetime_SendCmdToRingBuff(MID_ENROLL_SINGLE, databuf, len, cb, FACE_ENROLLING_TIMEOUT);

}

/**
  * @brief  发送0x12人脸验证
  * 
  * @param  time ：超时时间等于time*(FACE_VERITIFYING_TIMEOUT-FACE_MODULE_DEAL_TIMEOUT_SMALL)
  * @note
  *
  */
void Sensetime_Send_StartVerity_CMD(uint8_t time)
{
	uint8_t len = sizeof(s_msg_verify_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_verify_data *pdatabuf = (s_msg_verify_data *)databuf;
	FaceMessageCallback_fun_t cb = Sensetime_Verity_Callback;
	pdatabuf->timeout = time * (FACE_VERITIFYING_TIMEOUT - FACE_MODULE_DEAL_TIMEOUT_SMALL) / FACE_ONE_SEC_OF_MSEC;
	Sensetime_SendCmdToRingBuff(MID_VERIFY, databuf, len, cb, time * FACE_VERITIFYING_TIMEOUT);
}


/**
  * @brief  发送0x20删除单个人脸
  * 
  * @param  user_id 存储于人脸模组的用户ID
  * 
  * @note
  *
  */
void Sensetime_Send_Start_DelUser_CMD(uint16_t user_id)
{
	uint8_t len = sizeof(s_msg_deluser_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_deluser_data *pdatabuf = (s_msg_deluser_data *)databuf;

	pdatabuf->user_id_heb = (user_id >> 8) & 0xFF;
	pdatabuf->user_id_leb = user_id & 0xFF;
	FaceMessageCallback_fun_t cb = Sensetime_DelUser_Callback;
	Sensetime_SendCmdToRingBuff(MID_DELUSER, databuf, len, cb, FACE_DELETING_TIMEOUT);
}


/**
  * @brief  发送0x21删除全部人脸
  * 
  * @note
  */
void Sensetime_Send_Start_DelAll_CMD(void)
{
	FaceMessageCallback_fun_t cb = Sensetime_DelAll_Callback;
	Sensetime_SendCmdToRingBuff(MID_DELALL, NULL, 0, cb, FACE_DELETING_TIMEOUT);
}


/**
  * @brief  发送0x10终止当前操作指令（验证、注册）
  * 
  * @note
  */
void Sensetime_Send_Reset_CMD(void)
{
	uint32_t timeout = FACE_IDLE_TIMEOUT - FACE_MODULE_DEAL_TIMEOUT_SMALL;
	FaceMessageCallback_fun_t cb = Sensetime_Reset_Callback;
	Sensetime_SendCmdToRingBuff(MID_RESET, NULL, 0, cb, timeout);
}

                                     
/**
  * @brief  发送0xED掉电的消息
  * 
  * @note
  */
void Sensetime_Send_PowerDowm_CMD(void)
{
	FaceMessageCallback_fun_t cb = Sensetime_PowerDowm_Callback;
	Sensetime_SendCmdToRingBuff(MID_POWERDOWN, NULL, 0, cb, FACE_POWERDOWN_TIMEOUT);
}


/**
  * @brief  发送0x80特性设置
  * 
  * @note
  * @param flag
  * @return 
  */
void Sensetime_Send_SetAttribute_CMD(uint8_t flag)
{
	uint8_t len = sizeof(s_msg_attribute_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_attribute_data *pdatabuf = (s_msg_attribute_data *)databuf;
	FaceMessageCallback_fun_t cb = NULL;
	pdatabuf->flag = flag;
	Sensetime_SendCmdToRingBuff(MID_ENABLE_ATTRIBUTE, databuf, len, cb, FACE_NORMAL_TIMEOUT);
}

/**
  * @brief  发送0x23清除录入记录
  * 
  * @note
  */
void Sensetime_Send_FaceReset_CMD(void)
{
	Sensetime_SendCmdToRingBuff(MID_FACERESET, NULL, 0, NULL, FACE_FACE_RESET_TIMEOUT);
}

/*******************************************************************************/
/********************       操作指令发送函数   END     ************************/
/*******************************************************************************/

/*******************************************************************************/
/******************       加密指令相关处理函数  START          *******************/
/*******************************************************************************/


/**
  * @brief  发送0x50初始化随机数（设置加密模式）给人脸模组
  * 
  * @param  seed :随机序列(4个字节)
  * @param  time :当前时间戳(4个字节)
  * @note
  *
  */
void Sensetime_Send_InitEncryption_CMD(uint8_t *seed, uint8_t seedlen, uint8_t *time, uint8_t timelen)
{
	uint8_t len = sizeof(s_msg_init_encryption_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_init_encryption_data *pdatabuf = (s_msg_init_encryption_data *)databuf;
	memcpy(pdatabuf->seed, seed, 4);
	memcpy(pdatabuf->crttime, time, 4);
	pdatabuf->mode = ST_ENCMODE_AES; //AES加密模式
	FaceMessageCallback_fun_t cb = Sensetime_InitEncryption_Callback;
	Sensetime_SendCmdToRingBuff(MID_INIT_ENCRYPTION, databuf, len, cb, FACE_NORMAL_TIMEOUT);
}


/**
  * @brief  发送0x53临时加密key
  * 
  * @param  data :密钥的选择逻辑（16个字节）
  * @note
  */
void Sensetime_Send_DebugEncrytionKeyNum_Cmd(uint8_t *data, uint8_t datalen)
{
	uint8_t len = sizeof(s_msg_enc_key_number_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_enc_key_number_data *pdatabuf = (s_msg_enc_key_number_data *)databuf;
	memcpy(pdatabuf->enc_key_number, data, datalen);

	FaceMessageCallback_fun_t cb = Sensetime_DebugEncrytionKeyNum_Callback;
	Sensetime_SendCmdToRingBuff(MID_SET_DEBUG_ENC_KEY, databuf, len, cb, FACE_NORMAL_TIMEOUT);
}

/*******************************************************************************/
/******************       加密指令相关处理函数  END          *********************/
/*******************************************************************************/


/*******************************************************************************/
/******************       设置指令相关处理函数  START        *********************/
/*******************************************************************************/


/**
  * @brief  发送设置演示模式消息给人脸模组
  * 
  * @param  mode :0x01： demo       0x00：正常工作模式
  * @note
  *
  */
void Sensetime_Send_SetDemoMode_CMD(uint8_t mode)
{
	uint8_t len = sizeof(s_msg_set_debugmode);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_set_debugmode *pdatabuf = (s_msg_set_debugmode *)databuf;

	pdatabuf->mode = mode; //设置工作模式
	FaceMessageCallback_fun_t cb = Sensetime_SetDebugMode_Callback;
	Sensetime_SendCmdToRingBuff(MID_DEMOMODE, databuf, len, cb, FACE_NORMAL_TIMEOUT);
}


/**
  * @brief  发送获取软件版本消息给人脸模组
  * 
  * @param  mode :0x01： debug       0x00：正常工作模式
  * @note
  *
  */
void Sensetime_Send_Get_Version_CMD(void)
{
	uint8_t len = 1;
	uint8_t databuf[2] ={0};
	databuf[0] = 0x4B;
	FaceMessageCallback_fun_t cb = Sensetime_Get_Version_Callback;
	Sensetime_SendCmdToRingBuff(MID_GET_VERSION, databuf, len, cb, FACE_NORMAL_TIMEOUT);
}


/**
  * @brief  人脸设置量产加密秘钥序列
  * 
  * @param  data :密钥的选择逻辑（16个字节）
  * @note
  *
  */
void Sensetime_Send_ReleaseEncrytionKeyNum_Cmd(uint8_t *data, uint8_t datalen)
{
	uint8_t len = sizeof(s_msg_enc_key_number_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_enc_key_number_data *pdatabuf = (s_msg_enc_key_number_data *)databuf;
	memcpy(pdatabuf->enc_key_number, data, datalen);

	FaceMessageCallback_fun_t cb = Sensetime_ReleaseEncrytionKeyNum_Callback;
	Sensetime_SendCmdToRingBuff(MID_SET_RELEASE_ENC_KEY, databuf, len, cb, FACE_NORMAL_TIMEOUT);
}


/*******************************************************************************/
/******************       设置指令相关处理函数  END        *********************/
/*******************************************************************************/


/*******************************************************************************/
/******************       OTA指令相关处理函数  START        *********************/
/*******************************************************************************/

/**
  * @brief  发送启动升级的消息给人脸模组
  * 
  * @param  
  * @note
  *
  */
void Sensetime_Send_StartOta_CMD(void)
{
	uint8_t len = sizeof(s_msg_startota_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_startota_data *pdatabuf = (s_msg_startota_data *)databuf;
	FaceMessageCallback_fun_t cb = NULL;
	//pdatabuf->ota_type = type;
	pdatabuf->v_primary = 0x00;
	pdatabuf->v_secondary = 0x00;
	pdatabuf->v_revision = 0x00;
	cb = Sensetime_StartOta_Callback;

	Sensetime_SendCmdToRingBuff(MID_START_OTA, databuf, len, cb, FACE_MID_START_OTA_TIMEOUT);
}


/**
  * @brief  发送获取模块OTA状态消息给人脸模组
  * 
  * @param  
  * @note
  *
  */
void Sensetime_Send_GetOtaStatus_CMD(void)
{
	FaceMessageCallback_fun_t cb = Sensetime_GetOtaStatus_Callback;
	Sensetime_SendCmdToRingBuff(MID_GET_OTA_STATUS, NULL, 0, cb, FACE_MID_GET_OTA_STATUS_TIMEOUT);
}


/*******************************************************************************/
/******************       OTA指令相关处理函数  END        ***********************/
/*******************************************************************************/

/**
  * @brief  发送获取已注册的所有用户id给人脸模组
  * 
  * @param  
  * @note
  *
  */
void Sensetime_Send_GetAllUserid_CMD(void)
{
	FaceMessageCallback_fun_t cb = Sensetime_GetAllUserid_Callback;
	Sensetime_SendCmdToRingBuff(MID_GET_ALL_USERID, NULL, 0, cb, FACE_NORMAL_TIMEOUT);
}